package com.hyt.it.ogt.kq.main.controller.gov;


import cn.hutool.core.text.StrPool;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hyt.common.apiInfor.ApiResponse;
import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.common.exception.GovInvalidRequestException;
import com.hyt.it.ogt.kq.common.gov.config.arrange.CommonLockKeyCreator;
import com.hyt.it.ogt.kq.common.gov.config.swagger.ApiVersionConstant;
import com.hyt.it.ogt.kq.common.gov.constant.ResponseCode;
import com.hyt.it.ogt.kq.main.controller.base.BaseController;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeRoom;
import com.hyt.it.ogt.kq.service.gov.model.entity.TaskPlace;
import com.hyt.it.ogt.kq.service.gov.model.param.FiltrateRoomParam;
import com.hyt.it.ogt.kq.service.gov.model.param.OfficeRoomParam;
import com.hyt.it.ogt.kq.service.gov.model.param.TaskRoomParam;
import com.hyt.it.ogt.kq.service.gov.model.vo.FiltrateRoomPageVO;
import com.hyt.it.ogt.kq.service.gov.model.vo.TaskRoomQueryResultVO;
import com.hyt.it.ogt.kq.service.gov.model.vo.Tree;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeRoomService;
import com.hyt.it.ogt.kq.service.gov.service.ITaskRoomService;
import com.hyt.it.ogt.kq.service.gov.service.ITaskService;
import com.hyt.log.annotation.Log;
import com.hyt.model.PageParam;
import com.hyt.progress.creator.anno.ProgressAnno;
import com.hyt.swagger.ApiVersion;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiOperationSort;
import io.swagger.annotations.ApiSort;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 考场信息 前端控制器
 * </p>
 *
 * @author huangyh
 * @since 2021-03-08
 */
@RestController
@Api(tags = "119.考场接口", value = "考场接口")
@ApiSort(value = 119)
@RequestMapping("/kw/gov/room")
@Slf4j
public class RoomController extends BaseController {

    @Autowired
    private IOfficeRoomService iOfficeRoomService;

    @Autowired
    private ITaskRoomService iTaskRoomService;

    @Resource
    private ITaskService iTaskService;

    @Resource
    private RedisTemplate redisTemplate;

    @ApiOperation(
            value = "19.1 添加考场",
            notes = "30000:添加考场成功; 30140:添加考场异常; 30141:添加考场参数校验错误; 30149:当前考点下存在名称相同的考场"
    )
    @ApiOperationSort(value = 1)
    //@RequestMapping(value = "/add", method = RequestMethod.POST)
    @Deprecated
    public ApiResponse<Object> add(@Valid @RequestBody OfficeRoomParam officeRoomParam) {
        log.info("# 添加考场参数 ： {}", officeRoomParam.toString());
        try {
            String officeId = getOfficeId();
            iOfficeRoomService.add(officeRoomParam, officeId);
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .build();
        } catch (KqException kwGovException) {
            log.error("# 添加考场参数异常: ", kwGovException);
            return ApiResponse.builder()
                    .code(kwGovException.getErrCode())
                    .build();
        } catch (GovInvalidRequestException invalidRequestException) {
            log.error("# 请求异常: ", invalidRequestException);
            return ApiResponse.builder()
                    .code(invalidRequestException.getCode())
                    .build();
        } catch (Exception e) {
            log.error("# 添加考场参数异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_ADD_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.2 根据id查询考场详细信息",
            notes = "30000:根据id查询考场详细信息成功; 30144:根据id查询考场详细信息异常; 30145:考场id不能为空; 30146:考场已不存在"
    )
    @ApiOperationSort(value = 2)
    //@RequestMapping(value = "/query/{roomId}", method = RequestMethod.GET)
    @Deprecated
    public ApiResponse<Object> query(@PathVariable String roomId) {
        log.info("# 根据id查询考场详细信息参数 ： {}", roomId);
        try {
            if (StringUtils.isEmpty(roomId)) {
                //考场id不能为空
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_ID_IS_NULL.getCode())
                        .build();
            }
            QueryWrapper<OfficeRoom> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(OfficeRoom::getId, roomId)
                    .eq(OfficeRoom::getDelFlag, false);
            OfficeRoom officeRoom = iOfficeRoomService.getOne(queryWrapper);
            if (ObjectUtils.isEmpty(officeRoom)) {
                //考场已不存在
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_ONO_EXIST.getCode())
                        .build();
            }
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(officeRoom)
                    .build();
        } catch (Exception e) {
            log.error("# 根据id查询考场详细信息异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_DETAIL_INFO_QUERY_BY_ID_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.3 根据考点id查询考场信息分页数据",
            notes = "30000:根据考点id查询考场信息分页数据成功; 30147:根据考点id查询考场信息分页数据异常; 30148:考点id不能为空"
    )
    @ApiOperationSort(value = 3)
    //@RequestMapping(value = "/page", method = RequestMethod.GET)
    @Deprecated
    public ApiResponse<Object> page(PageParam<OfficeRoom> pageParam, String placeId) {
        log.info("# 根据考点id查询考场信息分页数据参数 ： {}, {}", pageParam.toString(), placeId);
        try {
            if (StringUtils.isEmpty(placeId)) {
                //考点id不能为空
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_PLACE_ID_CAN_NOT_NULL.getCode())
                        .build();
            }
            QueryWrapper<OfficeRoom> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(OfficeRoom::getPlaceId, placeId)
                    .eq(OfficeRoom::getDelFlag, false)
                    .orderByAsc(OfficeRoom::getCode);
            Page<OfficeRoom> page = iOfficeRoomService.page(pageParam, queryWrapper);
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(page)
                    .build();
        } catch (Exception e) {
            log.error("# 根据考点id查询考场信息分页数据异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_PAGE_QUERY_BY_ID_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.4 编辑考场",
            notes = "30000:编辑考场成功; 30151:编辑考场异常; 30152:编辑考场参数校验错误; 30150:当前考点下存在名称相同的考场; 30162:当前考场已不存在"
    )
    @ApiOperationSort(value = 4)
    //@RequestMapping(value = "/update", method = RequestMethod.POST)
    @Deprecated
    public ApiResponse<Object> update(@Valid @RequestBody OfficeRoomParam officeRoomParam) {
        log.info("# 编辑考场参数 ： {}", officeRoomParam.toString());
        try {
            iOfficeRoomService.update(officeRoomParam);
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .build();
        } catch (GovInvalidRequestException i) {
            log.error("# 编辑考场异常: {}", i.getMessage());
            return ApiResponse.builder()
                    .code(i.getCode())
                    .build();
        } catch (Exception e) {
            log.error("# 编辑考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_EDIT_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.5 删除考场",
            notes = "30000:删除考场成功; 30154:删除考场异常; 30155:考场id不能为空"
    )
    @ApiOperationSort(value = 5)
    //@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @Deprecated
    public ApiResponse<Object> delete(@RequestBody String roomIds) {
        log.info("# 删除考场参数 ： {}", roomIds);
        try {
            Map<String, String> map = JSON.parseObject(roomIds, Map.class);
            roomIds = map.get("roomIds");
            if (StringUtils.isEmpty(roomIds)) {
                //考场id不能为空
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_ID_IS_NULL.getCode())
                        .build();
            }
            List<String> roomIdList = Arrays.asList(roomIds.split(StrPool.COMMA));
            iOfficeRoomService.removeByIds(roomIdList);
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .build();
        } catch (Exception e) {
            log.error("# 编辑考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_REMOVE_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.6 筛选编排考点考场分页数据",
            notes = "30000:筛选编排考点考场分页数据成功; 30173:筛选编排考点考场分页数据异常; 30174:查询参数不能为空"
    )
    @ApiOperationSort(value = 6)
    //@RequestMapping(value = "/filtratePage", method = RequestMethod.GET)
    @Deprecated
    public ApiResponse<Object> filtratePage(PageParam<FiltrateRoomPageVO> pageParam, FiltrateRoomParam filtrateRoomParam) {
        log.info("# 根据考点id查询考场信息分页数据参数 ： {}, {}", pageParam.toString(), filtrateRoomParam.toString());
        try {

            String officeId = getOfficeId();
            Page<FiltrateRoomPageVO> page = iOfficeRoomService.filtratePage(pageParam, filtrateRoomParam, officeId);
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(page)
                    .build();
        } catch (KqException kwGovException) {
            log.error("# 筛选编排考点考场分页数据常: ", kwGovException.getErrMsg());
            return ApiResponse.builder()
                    .code(kwGovException.getErrCode())
                    .build();
        } catch (GovInvalidRequestException e) {
            log.error("# 请求异常: ", e);
            return ApiResponse.builder()
                    .code(e.getCode())
                    .build();
        } catch (Exception e) {
            log.error("# 筛选编排考点考场分页数据常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_PAGE_FILTER_PLACE_ROOM_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.7 添加编排考点考场",
            notes = "30000:添加编排考点考场成功; 30175:添加编排考点考场异常; 30176:考场id不能为空; 30177:考试任务id不能为空; 30178:添加的编排考场中存在重复的考场 30179:添加的编排考场中存在已被删除的考场，请刷新页面并重新选择后添加 30180:添加的编排考场中存在与当前任务已添加的考场重复的考场，请勿重复添加"
    )
    @ApiOperationSort(value = 7)
    @ApiVersion(group = ApiVersionConstant.V2_4_10)
    @PostMapping("/addArrangeRoom")
    //@NoRepeatCommit(lockName = "no-repeat-add-arrange-room-lock", leaseTime = 3L)
    public ApiResponse<Object> addArrangeRoom(@RequestBody TaskRoomParam taskRoomParam) {
        log.info("# 添加批次参数 ： {}", taskRoomParam.getRoomIds());
        String key = "no-repeat-add-arrange-room-lock" + taskRoomParam.getTaskId();
        if (!redisTemplate.opsForValue().setIfAbsent(key, 1)) {
            log.error("# 添加编排考点考场重复提交:");
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_ADD_ARRANGE_PLACE_ROOM_REPECT.getCode())
                    .build();
        }
        try {
            if (StringUtils.isEmpty(taskRoomParam.getRoomIds())) {
                //考场id不能为空
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_ID_IS_NULL.getCode())
                        .build();
            }
            if (StringUtils.isEmpty(taskRoomParam.getTaskId())) {
                //考试任务id不能为空
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_TASK_ID_CAN_NOT_NULL.getCode())
                        .build();
            }

            String officeId = getOfficeId();
            iTaskRoomService.addArrangeRoom(taskRoomParam.getRoomIds(), officeId, taskRoomParam.getTaskId());
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .build();
        } catch (KqException kwGovException) {
            log.error("# 添加编排考点考场异常: {}", kwGovException.getErrMsg());
            return ApiResponse.builder()
                    .code(kwGovException.getErrCode())
                    .build();
        } catch (Exception e) {
            log.error("# 添加编排考点考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_ADD_ARRANGE_PLACE_ROOM_EXCEPTION.getCode())
                    .build();
        } finally {
            redisTemplate.delete(key);
        }
    }

    @ApiOperation(
            value = "19.8 查询任务考点考场分页数据",
            notes = "30000:查询任务考点考场成功; "
    )
    @ApiOperationSort(value = 8)
    @ApiVersion(group = ApiVersionConstant.V2_4_10)
    @GetMapping("/getTaskPlaceRoom")
    public ApiResponse<Page<TaskRoomQueryResultVO>> getTaskPlaceRoom(Page<TaskRoomQueryResultVO> pageParam, String taskId) {
        try {
            return ApiResponse.<Page<TaskRoomQueryResultVO>>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(iTaskRoomService.getTaskRoom(pageParam, taskId))
                    .build();
        } catch (Exception e) {
            log.error("# 查询任务考点考场异常:", e);
            return ApiResponse.<Page<TaskRoomQueryResultVO>>builder()
                    .code(ResponseCode.ROOM_QUERY_TASK_PLACE_ROOM_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.9 查询任务考点考场统计",
            notes = "30000:查询任务考点考场统计成功; "
    )
    @ApiOperationSort(value = 9)
    @GetMapping("/getTaskRoomTotal")
    public ApiResponse<Object> getTaskRoomTotal(String taskId) {
        try {

            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(iTaskRoomService.getTaskRoomTotal(taskId))
                    .build();
        } catch (Exception e) {
            log.error("# 查询任务考点考场统计异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_QUERY_TASK_PLACE_ROOM_STATISTICS_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.10 删除任务考点考场",
            notes = "30000:删除任务考点考场成功; "
    )
    @ApiOperationSort(value = 10)
    @PutMapping("/removeTaskRoom")
    public ApiResponse<Object> removeTaskRoom(@RequestBody TaskRoomParam taskRoomParam) {
        try {
            if (StringUtils.isBlank(taskRoomParam.getRoomIds())) {
                return ApiResponse.builder()
                        .code(ResponseCode.ROOM_REMOVE_MAST_BE_SELECT.getCode())
                        .build();
            }
            iTaskRoomService.removeTaskRoom(taskRoomParam.getTaskId(), taskRoomParam.getRoomIds());
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .build();
        } catch (KqException k) {
            log.error("# 删除任务考点考场业务异常: {}", k.getErrMsg());
            return ApiResponse.builder()
                    .code(k.getErrCode())
                    .build();
        } catch (Exception e) {
            log.error("# 删除任务考点考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_REMOVE_TASK_PLACE_ROOM_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.11 查询任务下的考场",
            notes = "30000:查询任务下的考场成功; "
    )
    @ApiOperationSort(value = 11)
    @GetMapping("/getTaskRoom")
    public ApiResponse<Object> getTaskRoom(@RequestParam String taskId, @RequestParam String placeId, @RequestParam int arrangeState) {
        try {

            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(iTaskRoomService.getTaskRoom(taskId, placeId))
                    .build();
        } catch (Exception e) {
            log.error("# 查询任务下的考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_QUERY_TASK_ROOM_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.12 下载考场导入模板",
            notes = "30000:下载考场导入模板成功; 30196:下载考点考场导入模板异常；30197：该机构下未查询到区域数据"
    )
    @ApiOperationSort(value = 12)
    @ApiVersion(group = ApiVersionConstant.V2_4_10)
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        try {
            iTaskRoomService.downloadTemplate(response,getUser());
        } catch (KqException i) {
            log.error("# 下载考场导入模板异常: {}", i.getMessage());
        } catch (Exception e) {
            log.error("# 下载考场导入模板异常:", e);
        }
    }

    @ApiOperation(
            value = "19.13 考点考场信息导入",
            notes = "30000:考点考场信息导入成功;30192:Excel数据校验异常（动态显示data内容）;30193:考点考场导入异常；30194:导入文件不存在;30195:导入考场信息文件类型错误;"
    )
    @ApiOperationSort(value = 13)
    @ApiVersion(group = ApiVersionConstant.V2_4_10)
    @Log(module = "考点考场管理", business = "考点考场信息导入")
    @ProgressAnno(total = 100, timeoutSeconds = 60 * 10, errorCode = 43191301, canConcurrent = false, lockKeyCreator = CommonLockKeyCreator.class)
    @PostMapping(value = "/importExcel")
    public void importExcel(@RequestParam String fileUrl, @RequestParam String taskId) {
        iTaskRoomService.importExcel(fileUrl, taskId);
    }

    @ApiOperation(
            value = "19.14 考点考场信息导出"
    )
    @ApiOperationSort(value = 14)
    @ApiVersion(group = ApiVersionConstant.V2_4_10)
    @ProgressAnno(total = 100, timeoutSeconds = 60 * 10, errorCode = 43191301)
    @PostMapping(value = "/exportExcel")
    public void exportExcel(@RequestParam String taskId) {
        iTaskRoomService.exportExcel(taskId);
    }

    @ApiOperation(
            value = "19.15 查询任务下的考场",
            notes = "30000:查询任务下的考场成功; "
    )
    @ApiOperationSort(value = 15)
    @GetMapping("/getTaskRoomById")
    public ApiResponse<Object> getTaskRoomByTaskId(@RequestParam String taskId) {
        try {

            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(iTaskRoomService.getTaskRoomByTaskId(taskId))
                    .build();
        } catch (Exception e) {
            log.error("# 查询任务下的考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_QUERY_TASK_ROOM_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "19.16 查询任务下的考点",
            response = TaskPlace.class
    )
    @ApiOperationSort(value = 16)
    @GetMapping("/getTaskPlace")
    public ApiResponse<Object> getTaskPlace(@RequestParam String taskId, @RequestParam int arrangeState) {
        try {
            return ApiResponse.builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(iTaskRoomService.getTaskPlace(taskId, arrangeState))
                    .build();
        } catch (Exception e) {
            log.error("# 查询任务下的考场异常:", e);
            return ApiResponse.builder()
                    .code(ResponseCode.ROOM_QUERY_TASK_ROOM_EXCEPTION.getCode())
                    .build();
        }
    }

    @ApiOperation(
            value = "28.4 获取考点区域树",
            notes = "20000:成功"
    )
    @GetMapping("/allTree")
    public ApiResponse<List<Tree>> allTree(@RequestParam String taskId, @RequestParam(required = false) String type) {
        log.info("# 获取考点区域树: ");
        try {
            List<Tree> candidateAreaListVOList = iTaskRoomService.allTree(taskId,type);
            return ApiResponse.<List<Tree>>builder()
                    .code(ResponseCode.SUCCESS.getCode())
                    .data(candidateAreaListVOList)
                    .build();
        } catch (Exception e) {
            log.error("# 获取考生区县级区域下拉列表失败", e);
            return ApiResponse.<List<Tree>>builder()
                    .code(ResponseCode.GET_DISTRICT_LIST_EXCEPTION.getCode())
                    .build();
        }
    }

}
